<?php

namespace app\command;

use app\model\UserBalanceLog;
use app\model\UserBalanceWithdrawalLogModel;
use app\service\WxPayService;
use Exception;
use schedule\console\Command;
use think\console\Input;
use think\console\Output;
use think\Db;
use think\facade\Log;

class UpgradeTransferCommissionLogCommand extends Command
{
	protected function configure()
	{
		$this->setName('upgradeTransferCommissionLog')->setDescription('用户提现记录失败恢复脚本');
	}

	/**
	 * @throws Exception
	 */
	protected function execute(Input $input, Output $output)
	{
		Log::init([
			'type'      => 'file',
			'path'      => app()->getRootPath() . 'runtime/log/payQuery/',
			'level'     => ['info', 'error', 'sql', 'alert'],
			'max_files' => 10,
			'file_size' => 1024 * 1024 * 100,
		]);


		// 查询用户提现状态为失败的记录
		$userBalanceLogList = UserBalanceLog::whereIn('account_status', [
			UserBalanceLog::ACCOUNT_STATUS_FAIL,
			UserBalanceLog::ACCOUNT_STATUS_REVOKE,
		])->where('type', UserBalanceLog::TYPE_REAL_TIME)
			->select()
			->toArray();
		foreach ($userBalanceLogList as $item) {
			try {
				$result = WxPayService::getInstance()->queryTransferOrder($item['order_id']);
				switch ($result['state']) {
					case 'FAIL': // 转账失败
					case 'CANCELLED': // 转账撤销完成
						// 转账失败和转账撤销，则将数据重新提现数据重新更新为待提现状态
						$this->resetUserBalanceLogStatus($item);
						break;
					case 'SUCCESS':
						// 转账成功，则将订单置为转账成功状态
						$this->successUserBalanceLogStatus($item, $result);
						break;
				}
			} catch (Exception $e) {
				Log::error(['执行失败', [$item]]);
				Log::error(['Exception', [$e]]);
			}
		}
	}

	/**
	 * 将订单状态重置为待转账
	 *
	 * @param $item
	 * @return void
	 */
	protected function resetUserBalanceLogStatus($item): void
	{
		// 查询用户自动提现记录
		$withdrawalLog = UserBalanceWithdrawalLogModel::field('id,user_id,user_balance_id,type,order_no,status')
			->where('user_balance_id', $item['log_id'])
			->where('status', UserBalanceWithdrawalLogModel::STATUS_WAIT)
			->find();

		// 新增用户自动提现记录
		$createData = [
			'user_id'          => $item['user_id'],
			'user_balance_id'  => $item['log_id'],
			'type'             => UserBalanceWithdrawalLogModel::TYPE_WECHAT,
			'order_no'         => $this->buildOrderNo(),
			'transfer_bill_no' => '',
			'money'            => intval($item['money'] * 100),
			'status'           => UserBalanceWithdrawalLogModel::STATUS_WAIT,
			'created_at'       => date('Y-m-d H:i:s'),
			'updated_at'       => date('Y-m-d H:i:s'),
		];

		// 更新
		DB::transaction(function () use ($item, $withdrawalLog, $createData) {
			// 将提现记录初始化为未提现状态
			UserBalanceLog::where('log_id', $item['log_id'])->update([
				'account_status' => UserBalanceLog::ACCOUNT_STATUS_WAIT,
			]);
			// 存在未完成记录，则改为撤销状态
			if ($withdrawalLog) {
				UserBalanceWithdrawalLogModel::where('id', $withdrawalLog['id'])->update([
					'status' => UserBalanceWithdrawalLogModel::STATUS_CANCEL,
				]);
			}
			// 重新创建转账记录(@tips: 生成新的转账订单号)
			UserBalanceWithdrawalLogModel::create($createData);
		});
	}

	/**
	 * 将订单状态改为转账成功
	 *
	 * @param $item
	 * @param $result
	 * @return void
	 */
	protected function successUserBalanceLogStatus($item, $result): void
	{
		// 查询用户自动提现记录
		$withdrawalLog = UserBalanceWithdrawalLogModel::field('id,user_id,user_balance_id,type,order_no,status')
			->where('user_balance_id', $item['log_id'])
			->where('status', UserBalanceWithdrawalLogModel::STATUS_WAIT)
			->find();

		// 更新
		DB::transaction(function () use ($item, $withdrawalLog, $result) {
			// 将提现记录初始化为完成状态
			UserBalanceLog::where('log_id', $item['log_id'])->update([
				'account_status' => UserBalanceLog::ACCOUNT_STATUS_COMPLETED,
			]);
			// 存在未完成记录，则改为完成状态
			if ($withdrawalLog) {
				UserBalanceWithdrawalLogModel::where('id', $withdrawalLog['id'])->update([
					'status'           => UserBalanceWithdrawalLogModel::STATUS_COMPLETE,
					'transfer_bill_no' => $result['transfer_bill_no'],
				]);
			}
		});
	}

	private function buildOrderNo(): string
	{
		return date('ymd') . substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
	}
}